struct task_struct
{
    /*...*/
    struct mm_struct *mm; //对于普通的用户进程来说该字段指向他的虚拟地址空间的用户的空间部分，对于内核线程来说这部分为NULL。
    struct mm_struct *active_mm; // 该字段是内核线程使用的。当该进程是内核线程时，它的mm字段为NULL，表示没有内存地址空间，可也并不是真正的没有，这是因为所有进程关于内核的映射都是一样的，内核线程可以使用任意进程的地址空间。
    /*...*/
};



struct mm_struct
{
  /*...*/
  struct vm_area_struct *mmap; /* 指向虚拟区间(VMA)链表 */
  struct rb_root mm_rb; /* red_black树 */
  unsigned long task_size; /*具有该结构体的进程的虚拟地址空间的⼤⼩*/
  /*...*/
  // 代码段、数据段、堆栈段、参数段及环境段的起始和结束地址。
  unsigned long start_code, end_code, start_data, end_data;
  unsigned long start_brk, brk, start_stack;
  unsigned long arg_start, arg_end, env_start, env_end;
  /*...*/
};



struct vm_area_struct 
{
  unsigned long vm_start; //虚存区起始
  unsigned long vm_end; //虚存区结束
  struct vm_area_struct *vm_next, *vm_prev; //前后指针
  struct rb_node vm_rb; //红黑树中的位置
  unsigned long rb_subtree_gap;
  struct mm_struct *vm_mm; //所属的 mm_struct
  pgprot_t vm_page_prot;
  unsigned long vm_flags; //标志位
  struct 
  {
    struct rb_node rb;
    unsigned long rb_subtree_last;
  } shared;
  struct list_head anon_vma_chain;
  struct anon_vma *anon_vma;
  const struct vm_operations_struct *vm_ops; //vma对应的实际操作
  unsigned long vm_pgoff; //⽂件映射偏移量
  struct file * vm_file; //映射的⽂件
  void * vm_private_data; //私有数据
  atomic_long_t swap_readahead_info;
#ifndef CONFIG_MMU
  struct vm_region *vm_region; /* NOMMU mapping region */
#endif
#ifdef CONFIG_NUMA
  struct mempolicy *vm_policy; /* NUMA policy for the VMA */
#endif
  struct vm_userfaultfd_ctx vm_userfaultfd_ctx;
} __randomize_layout;
